#ifndef COMMON_FILE_H_
#define COMMON_FILE_H_

#include <fermat/common/timestamp.h>
#include <vector>
#include <string>
#include <cstddef>

namespace fermat {


class Path;

class  File {
public:
	typedef size_t FileSize;
public:

	File();
	
	File(const std::string& path);
		
	File(const char* path);
	
	File(const Path& path);
		
	File(const File& file);
	
	virtual ~File();
	
	File& operator = (const File& file);
	
	File& operator = (const std::string& path);
	
	File& operator = (const char* path);
	
	File& operator = (const Path& path);
		
	void swap(File& file);
	
	const std::string& path() const;
	
	bool exists() const;
		
	bool canRead() const;
		
	bool canWrite() const;
	
	bool canExecute() const;
	
	bool isFile() const;
		
	bool isLink() const;
		
	bool isDirectory() const;
		
	bool isDevice() const;
	
	bool isHidden() const;
	
	Timestamp created() const;
	
	Timestamp getLastModified() const;
		
	bool setLastModified(const Timestamp& ts);
		
	FileSize getSize() const;
		
	bool setSize(FileSize size);
		
	bool setWriteable(bool flag = true);
		
	bool setReadOnly(bool flag = true);
		
	bool setExecutable(bool flag = true);
		
	bool copyTo(const std::string& path) const;
	
	bool moveTo(const std::string& path);
		
	bool renameTo(const std::string& path);
		
	bool remove(bool recursive = false);
	
	bool createFile();

	bool readToString(std::string &content, FileSize limited = 65536);
	
	bool writeToFile(const char* buff, FileSize size);

	bool writeToFile(std::string &content);


	bool createDirectory();
	
	bool createDirectories();
		
	void list(std::vector<std::string>& files) const;
	
	void list(std::vector<File>& files) const;
	
	int valid();
	bool operator == (const File& file) const;
	bool operator != (const File& file) const;
	bool operator <  (const File& file) const;
	bool operator <= (const File& file) const;
	bool operator >  (const File& file) const;
	bool operator >= (const File& file) const;
	
private:
	bool copyDirectory(const std::string& path) const;
	bool copyFile(const std::string& path) const;
	int  init(const std::string &path);
	mutable int  _rc;
	std::string _path;
	
	
};


//
// inlines
//
inline int File::valid()
{
	return _rc == 0 && !_path.empty();
}
inline const std::string& File::path() const
{
	return _path;
}


inline bool File::operator == (const File& file) const
{
	return _path == file._path;
}


inline bool File::operator != (const File& file) const
{
	return _path != file._path;
}


inline bool File::operator < (const File& file) const
{
	return _path < file._path;
}


inline bool File::operator <= (const File& file) const
{
	return _path <= file._path;
}


inline bool File::operator > (const File& file) const
{
	return _path > file._path;
}


inline bool File::operator >= (const File& file) const
{
	return _path >= file._path;
}


inline void swap(File& f1, File& f2)
{
	f1.swap(f2);
}


} 


#endif 
